#ifndef PIX_HPP
#define PIX_HPP

#include <QObject>
#include <QThread>
#include <QFile>
#include <QTimer>

#include "datamemoryorganisation.hpp"
#include "cpu.hpp"
#include "simulatortime.hpp"
#include "decoder.hpp"
#include "stackmanagement.hpp"
#include "command.hpp"
#include "programmanagement.hpp"
#include "watchdog.hpp"
#include "interruptcontroller.hpp"

/**
* @brief
*
* @class Pix pix.hpp "pix.hpp"
*/
class Pix : public QThread
{
    Q_OBJECT

public:

    enum simulationModeEnum {STOP, PAUSE, RUN, TRACE, BREAK, SLEEP};

    /**
    * @brief Creates a new instance
    *
    * @fn Pix
    */
    Pix();

    /**
    * @brief Destructs the instance
    *
    * @fn ~Pix
    */
    ~Pix();

    /**
    * @brief Reads the input file line by line
    * @details Creates a command object of every line
    *
    * @fn readCodeFile
    * @param filepath
    */
    void readCodeFile(const QString filepath);

    /**
    * @brief Returns a Pointer to the ProgramManagement
    *
    * @fn getProgramManagement
    * @return const ProgramManagement
    */
    ProgramManagement *getProgramManagement();

    /**
    * @brief Returns a Pointer to the DataMemoryOrganisation
    *
    * @fn getDataMemoryOrganisation
    * @return const DataMemoryOrganisation
    */
    DataMemoryOrganisation *getDataMemoryOrganisation();

    /**
    * @brief Returns a Pointer to the Decoder
    *
    * @fn getDecoder
    * @return Decoder
    */
    Decoder *getDecoder() const;

    /**
    * @brief Returns a Pointer to the StackManagement
    *
    * @fn getStackManagement
    * @return StackManagement
    */
    StackManagement *getStackManagement();

    /**
    * @brief Returns a Pointer to the CPU
    *
    * @fn getCPU
    * @return CPU
    */
    CPU *getCPU();

    /**
    * @brief Returns a Pointer to the Watchdog
    *
    * @fn getWatchdog
    * @return Watchdog
    */
    Watchdog *getWatchdog();

    /**
    * @brief Sets the simulationMode
    *
    * @fn setSimulationMode
    * @param simulationMode
    */
    void setSimulationMode(simulationModeEnum simulationMode);

    /**
    * @brief Resets all values of PIX
    *
    * @fn reset
    */
    void reset();

    void resetToProgramStart();

    /**
    * @brief Starts the Thread
    *
    * @fn run
    */
    void run();

    void stop();

    void pause();

    void setFastMode(bool state);

    int getProgramCounter() const;

private:
    Decoder *decoder;
    ProgramManagement *programManagement;
    DataMemoryOrganisation *dataMemoryOrganisation;
    StackManagement *stackManagement;
    Watchdog *watchdog;
    CPU *cpu;
    simulationModeEnum simulationMode;
    int programCounter;
    int waitInterval;
    bool fastMode;

signals:
    void programCounterChanged(int pc);
    void simulationStateChanged(bool state, int line);

};

#endif // PIX_HPP
